<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>预解析</title>
</head>
<body>
    <script>

        // 在代码执行之前 对代码进行通读并且解释
        //只解析两部分内容
        // 1. var 声明的变量名;
        // => 仅仅是对var 声明的变量提前声明 暂时不赋值 
        // 2. 声明式的函数
        // => 对函数名字提前声明 并且直接给这个函数名赋值了 一个函数
        // => 赋值式的函数按照  var 变量的规则进行  解释 


        // 注意点: 
        // 打开浏览器 只会解析全局代码 
        // 不对函数内的代码进行预解析
        // 函数内的代码 仅仅会在函数调用的时候才会 预解析  
        // var num = 100;
        // console.log(num);

        // 变量 
        //打开浏览器 
        // 1.var num = 100
        // 2.console.log(100)


        // 预解析
        // 第一步需要预解析  告诉浏览器 定义了一个叫做num的变量 但是不赋值 
        // 第二步.不需要预解析

        //代码执行
        // 1.num = 100 
        // 2.打印num的值

        console.log(num);
        var num = 100;
        console.log(num);

        

        // 打开浏览器 

        // 1 . console.log(num);
        // 2. var num = 100;
        // 3. console.log(num);

        // 预解析 

        // 1 .不需要
        // 2. 需要预解析  告诉浏览器 定义了一个叫做num的变量 但是不赋值
        // 3. 不需要

        // 代码执行 
        // 1. console.log(num); 因为预解析的时候仅仅是 声明 但是没有赋值  
        //所以结果是undefined  
        // 2. num = 100 
        // 3 打印num 的值输出到控制台  

        // 等价于下面代码
        // var num;
        // console.log(num);
        // num = 100;
        // console.log(num);

        //函数

        //fn()
        //function fn(){console.log('卧榻之侧岂容他人鼾睡')}
        //fn()


        // 打开浏览器  
        // 1.fn()
        // 2.function fn(){console.log('卧榻之侧岂容他人鼾睡')}
        // 3.fn()

        // 预解析  
        // 1.不需要 
        // 2.需要 声明了一个fn的变量 并且将函数赋值给了 fn 
        // 3. 不需要 


        // 代码执行
        // 1. fn()
        // => 把fn当做一个函数用 因为解析的时候已经声明了一个fn变量并且给他赋值为一个
        // 函数所以 这里会正常调用 
        // 2. fn() 
        // 跟上面一样

        // 等价于 
        // function fn(){console.log('卧榻之侧岂容他人鼾睡')}
        // fn()
        // fn()

        //赋值式的函数
        // fn() 
        // var fn = function(){console.log('卧榻之侧岂容他人鼾睡')}
        // fn()

        // 预解析完了之后 fn是个变量 没有赋值 

        //打开浏览器 
        // fn() 
        // var fn = function(){console.log('卧榻之侧岂容他人鼾睡')}
        // fn()


        //预解析 
        // 1.不需要
        // 2.需要 
        //  声明一个fn的变量 但是不赋值
        // 3.不需要解析


        // 代码执行
        // 1.把fn 当做函数来调用
        // => 预解析阶段我们已经声明了函数 但是没有赋值
        // => 此时的fn是一个undefined,你把undefined当做一个函数来调用
        // 2. 给fn 一个赋值 将函数赋值给fn 
        // 3.把 fn 当做一个正常的函数用 正常执行  


        function fn(){
            var num = 100;
            console.log(num)
        }
        // 如果仅仅写了上面代码 没有调用 也会预解析 
        // 声明变量 并且将 函数赋值给它  这时候不解析函数内部 
        // fn()   
        // 当调用的时候才解析函数内容不 

        // 预解析  
        // 直接声明一个fn的变量 并且将一个函数赋值给它
    

        //代码执行  
        // fn() 
        // 函数内部 预解析 
         // 解析var 变量 仅仅声明 没有赋值

         // 函数内部执行 
         // num = 100 
         //  输出到控制台 


    </script>
</body>
</html>